<template>
  <div class="confusion-matrix-container">
    <!-- 混淆矩阵和评估指标 -->
    <div class="matrix-section">
      <h2 class="section-title">混淆矩阵和评估指标</h2>
      <div class="threshold-slider" v-if="parsedMatrixData.length > 1">
        <span>阈值: {{ currentThreshold.toFixed(1) }}</span>
        <a-slider
          v-model="thresholdIndex"
          :min="0"
          :max="parsedMatrixData.length - 1"
          :step="1"
          @change="updateMatrix"
        />
      </div>

      <!-- 新的混淆矩阵卡片式布局 -->
      <div class="matrix-grid" v-if="currentMatrix">
        <!-- 顶部标题行 -->
        <div class="matrix-header">
          <div class="header-corner"></div>
          <div class="header-title">
            <div class="prediction-title">模型预测</div>
            <div class="prediction-labels">
              <div class="prediction-positive">模型预测(正)</div>
              <div class="prediction-negative">模型预测(负)</div>
            </div>
          </div>
          <div class="header-total">总数</div>
        </div>

        <!-- 数据行 -->
        <div class="matrix-rows">
          <!-- 实际值(正)行 -->
          <div class="matrix-row">
            <div class="row-label actual-positive">实际值(正)</div>
            <div class="matrix-cells">
              <div class="matrix-cell tp-cell">
                <div class="cell-label">tp</div>
                <div class="cell-value">{{ currentMatrix.tp }}</div>
              </div>
              <div class="matrix-cell fn-cell">
                <div class="cell-label">fn</div>
                <div class="cell-value">{{ currentMatrix.fn }}</div>
              </div>
            </div>
            <div class="row-total">
              <div class="total-label">totalTpFn</div>
              <div class="total-value">{{ currentMatrix.totalTpFn }}</div>
            </div>
          </div>

          <!-- 实际值(负)行 -->
          <div class="matrix-row">
            <div class="row-label actual-negative">实际值(负)</div>
            <div class="matrix-cells">
              <div class="matrix-cell fp-cell">
                <div class="cell-label">fp</div>
                <div class="cell-value">{{ currentMatrix.fp }}</div>
              </div>
              <div class="matrix-cell tn-cell">
                <div class="cell-label">tn</div>
                <div class="cell-value">{{ currentMatrix.tn }}</div>
              </div>
            </div>
            <div class="row-total">
              <div class="total-label">totalFpTn</div>
              <div class="total-value">{{ currentMatrix.totalFpTn }}</div>
            </div>
          </div>

          <!-- 总数行 -->
          <div class="matrix-row total-row">
            <div class="row-label total-label-cell">总数</div>
            <div class="matrix-cells">
              <div class="matrix-cell total-cell">
                <div class="cell-label">totalTpFp</div>
                <div class="cell-value">{{ currentMatrix.totalTpFp }}</div>
              </div>
              <div class="matrix-cell total-cell">
                <div class="cell-label">totalFnTn</div>
                <div class="cell-value">{{ currentMatrix.totalFnTn }}</div>
              </div>
            </div>
            <div class="row-total total-final">
              <div class="total-value">{{ currentMatrix.total }}</div>
            </div>
          </div>
        </div>
      </div>

      <div v-else class="no-data">
        <p>暂无混淆矩阵数据</p>
      </div>
    </div>

    <!-- 评估指标柱状图 -->
    <div class="metrics-chart" v-if="currentMatrix">
      <chart-card title="评估指标">
        <bar :data="chartData" />
      </chart-card>
    </div>
  </div>
</template>

<script>
import Bar from '@/components/Charts/Bar.vue'
import ChartCard from '@/components/Charts/ChartCard.vue'

export default {
  name: 'ConfusionMatrix',
  components: {
    Bar,
    ChartCard
  },
  props: {
    confusionMatrixData: {
      type: Array,
      required: true,
      default: () => []
    }
  },
  data() {
    return {
      thresholdIndex: 0
    }
  },
  computed: {
    // 解析字符串格式的混淆矩阵数据
    parsedMatrixData() {
      if (!this.confusionMatrixData || !Array.isArray(this.confusionMatrixData)) {
        return []
      }

      return this.confusionMatrixData
        .filter(item => item !== null && item !== undefined)
        .map(item => {
          try {
            if (typeof item === 'string') {
              return JSON.parse(item)
            }
            return item
          } catch (error) {
            console.error('解析混淆矩阵数据失败:', error, item)
            return null
          }
        })
        .filter(item => {
            return item !== null && Array.isArray(item) && item.length === 2
        })
    },

    currentThreshold() {
      return 0.5 + (this.thresholdIndex * 0.1)
    },

    currentMatrix() {
      if (!this.parsedMatrixData.length || this.thresholdIndex >= this.parsedMatrixData.length) {
        return null
      }

      const matrix = this.parsedMatrixData[this.thresholdIndex]
      if (!matrix || !Array.isArray(matrix) || matrix.length !== 2) {
        return null
      }

      const tp = matrix[0][0] // 真正例
      const fn = matrix[0][1] // 假负例
      const fp = matrix[1][0] // 假正例
      const tn = matrix[1][1] // 真负例

      return {
        tp,
        fn,
        fp,
        tn,
        totalTpFn: tp + fn,
        totalFpTn: fp + tn,
        totalTpFp: tp + fp,
        totalFnTn: fn + tn,
        total: tp + fn + fp + tn
      }
    },

    metrics() {
      if (!this.currentMatrix) {
        return {
          accuracy: 0,
          f10: 0,
          f11: 0,
          precision0: 0,
          precision1: 0,
          recall0: 0,
          recall1: 0,
          tnr: 0,
          tpr: 0
        }
      }

      const { tp, fn, fp, tn } = this.currentMatrix

      const accuracy = (tp + tn) / (tp + tn + fp + fn) || 0
      const precision0 = tp / (tp + fp) || 0
      const precision1 = tn / (tn + fn) || 0
      const recall0 = tp / (tp + fn) || 0
      const recall1 = tn / (tn + fp) || 0
      const f10 = 2 * (precision0 * recall0) / (precision0 + recall0) || 0
      const f11 = 2 * (precision1 * recall1) / (precision1 + recall1) || 0
      const tpr = recall0
      const tnr = recall1

      return {
        accuracy,
        f10,
        f11,
        precision0,
        precision1,
        recall0,
        recall1,
        tnr,
        tpr
      }
    },

    // 为 Bar 组件准备数据
    chartData() {
      if (!this.currentMatrix) {
        return []
      }

      const metricsLabels = {
        accuracy: '准确率',
        f10: 'F1分数(类别0)',
        f11: 'F1分数(类别1)',
        precision0: '精确率(类别0)',
        precision1: '精确率(类别1)',
        recall0: '召回率(类别0)',
        recall1: '召回率(类别1)',
        tnr: '真负率',
        tpr: '真正率'
      }

      return Object.keys(this.metrics).map(key => ({
        x: metricsLabels[key] || key,
        y: (this.metrics[key] * 100).toFixed(2) // 转换为百分比
      }))
    }
  },

  watch: {
    confusionMatrixData: {
      handler() {
        this.thresholdIndex = 0
      },
      immediate: true
    }
  },

  methods: {
    updateMatrix() {
      // 阈值变化时触发数据更新，由于使用了计算属性，数据会自动更新
    }
  }
}
</script>

<style scoped>
.confusion-matrix-container {
  padding: 24px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
}

.section-title {
  text-align: center;
  margin-bottom: 32px;
  font-size: 20px;
  font-weight: 600;
  color: #1a1a1a;
  letter-spacing: 0.5px;
}

.threshold-slider {
  margin-bottom: 40px;
  text-align: center;
}

.threshold-slider span {
  display: block;
  margin-bottom: 16px;
  font-weight: 600;
  color: #1890ff;
  font-size: 16px;
}

/* 新的矩阵网格布局 */
.matrix-grid {
  max-width: 800px;
  margin: 0 auto;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}

.matrix-header {
  display: grid;
  grid-template-columns: 120px 1fr 120px;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-bottom: 2px solid #dee2e6;
}

.header-corner {
  background: #f1f3f4;
  border-right: 1px solid #dee2e6;
}

.header-title {
  padding: 16px;
  text-align: center;
  border-right: 1px solid #dee2e6;
}

.prediction-title {
  font-size: 16px;
  font-weight: 600;
  color: #495057;
  margin-bottom: 12px;
}

.prediction-labels {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
}

.prediction-positive,
.prediction-negative {
  padding: 8px;
  font-size: 14px;
  font-weight: 500;
  color: #6c757d;
  background: rgba(255, 255, 255, 0.8);
  border-radius: 6px;
}

.header-total {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: 600;
  color: #495057;
  background: #f8f9fa;
}

.matrix-rows {
  background: #fff;
}

.matrix-row {
  display: grid;
  grid-template-columns: 120px 1fr 120px;
  border-bottom: 1px solid #e9ecef;
}

.matrix-row:last-child {
  border-bottom: none;
}

.row-label {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px 16px;
  font-size: 14px;
  font-weight: 600;
  border-right: 1px solid #e9ecef;
  writing-mode: horizontal-tb;
}

.actual-positive {
  background: linear-gradient(135deg, #e8f5e8 0%, #d4edda 100%);
  color: #155724;
}

.actual-negative {
  background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
  color: #856404;
}

.total-label-cell {
  background: linear-gradient(135deg, #e2e3e5 0%, #d6d8db 100%);
  color: #495057;
}

.matrix-cells {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: #e9ecef;
  border-right: 1px solid #e9ecef;
}

.matrix-cell {
  padding: 24px 16px;
  text-align: center;
  background: #fff;
  transition: all 0.3s ease;
  cursor: pointer;
}

.matrix-cell:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.cell-label {
  font-size: 12px;
  font-weight: 500;
  color: #6c757d;
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.cell-value {
  font-size: 24px;
  font-weight: 700;
  line-height: 1;
}

/* 不同类型单元格的颜色 */
.tp-cell {
  background: linear-gradient(135deg, #d1ecf1 0%, #bee5eb 100%);
}

.tp-cell .cell-value {
  color: #0c5460;
}

.fn-cell {
  background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%);
}

.fn-cell .cell-value {
  color: #721c24;
}

.fp-cell {
  background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
}

.fp-cell .cell-value {
  color: #856404;
}

.tn-cell {
  background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
}

.tn-cell .cell-value {
  color: #155724;
}

.total-cell {
  background: linear-gradient(135deg, #e2e3e5 0%, #d6d8db 100%);
}

.total-cell .cell-value {
  color: #495057;
}

.row-total {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px 16px;
  background: linear-gradient(135deg, #e8f4fd 0%, #d1ecf1 100%);
  border-radius: 0;
}

.total-label {
  font-size: 12px;
  font-weight: 500;
  color: #6c757d;
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.total-value {
  font-size: 20px;
  font-weight: 700;
  color: #0c5460;
}

.total-final {
  background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
}

.total-final .total-value {
  color: #155724;
  font-size: 24px;
}

.metrics-chart {
  margin-top: 200px;
}

.no-data {
  text-align: center;
  padding: 60px;
  color: #6c757d;
  font-size: 16px;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-radius: 12px;
}

@media (max-width: 768px) {
  .matrix-grid {
    font-size: 12px;
  }

  .matrix-row {
    grid-template-columns: 100px 1fr 100px;
  }

  .matrix-cell {
    padding: 16px 8px;
  }

  .cell-value {
    font-size: 18px;
  }

  .total-value {
    font-size: 16px;
  }
}
</style>
